iT邦幫忙

3

[AI Agent 架構筆記] 記憶系統真正的敵人不是忘記,而是錯誤地一直記得——我做 AI 長期記憶的結構化設計與翻車實錄

  • 分享至 

  • xImage
  •  

[2026 實戰筆記] 端午連假愉快。這篇可以單獨讀,不需要先看我的設計日誌。我想丟出一個鮮明的主張,再用實作(和翻車)把它撐起來;讀完若想看更底層的拆解,文末有完整章節連結。

歷史總是不斷重演。整部文明史,說穿了就是同一個循環:收集資料 → 處理資料 → 分析資料,然後再收集更多。而每一個世代,都在為「該怎麼裝這些資料」吵架:從關聯式資料庫(RDB)、到 NoSQL、再到大數據(Big Data),一波一波的技術浪潮,本質上都在回答同一個問題:這個世代的資料,到底該怎麼存、怎麼撈?

現在,輪到 AI 了。而且這次的題目更尷尬:AI 的「記憶」該怎麼處理——結構化,還是非結構化? 幾乎每篇入門教學的標準答案,都是 RAG(檢索增強生成)+向量資料庫:把東西全切碎、轉成向量、丟進去、再撈出來。但這其實只是「聲音最大」的那個。真正認真做長期記憶的,早就往結構化、知識圖譜、時序記憶那邊走了(純向量撈回來是一坨扁平的相似片段,沒有關係、也沒有時間軸)。我自己土法煉鋼做完一輪後也站同一邊,而且想得更極端一點——把整段對話塞進向量庫,那到底是在存「記憶」,還是只是把「文件」存起來而已?

先把整篇的核心論點一句講完:

長期記憶不該儲存「對話紀錄」,而該儲存「狀態、事件與知識」。

下面是這句話為什麼成立、以及怎麼落地。

先講那個你一定遇過的痛

你跟 ChatGPT(或 Claude、Gemini)深聊了京都自由行。一週後想接續:「上次那份飯店清單你還記得嗎?」——剛好點回同一個視窗,它接得上;順手開了新視窗,它當場失憶。

這個本質差異,技術上叫「跨 Session(跨對話階段)」難題:主流 AI 介面都是「同一視窗內記得,換一個視窗歸零」。對「問完即走」很合理,但你要把它當長期助理,就是災難,沒人想每次見私人秘書都重新自我介紹一次。

而業界想跨視窗記住你,目前大致三條路:長對話上下文(整年塞進去,token 爆、長了仍會爆)、自動摘要(必丟細節、無法事實稽核)、結構化記憶(拆成可檢索的結構,要用時精準撈)。前兩條的共同盲點,就是它們本質上都還在存「對話」。我選第三條,也就是本篇的主張。

把記憶拆成三種「卡片」

與其塞整段對話,不如把它拆成原子化的小卡(卡片盒筆記、Obsidian 都是這哲學)。我分三類:

  • 狀態卡(State):此刻為真的動態事實。[現居地: 台北][專案進度: 開源前驗收]。會被更新、取代。
  • 事件卡(Event):過去某時間點發生過的事。[2026-04-30 決策: 選 B 路徑]。累積、不覆蓋歷史。
  • 知識卡(Knowledge):抽象概念。[JWT 的運作原理]。可跨對話引用、互相連結。

再加一個藏在三者底下的第四維——時間。

為什麼硬要把「狀態」和「事件」分開? 因為它們解的是兩種不同的問題:問「我現在住哪?」要的是狀態(最新唯一真相),不該逼 AI 把十年搬家史讀完自己推;問「當時為什麼那樣決定?」要的是事件(過去那個不變的座標),狀態卡根本答不出來。所以:狀態卡可被取代、回答「現在」;事件卡只准累積、回答「過去」。

幾個讓它真的能用的設計

魔鬼在維運:

  • 會替換 vs 會累積(Cardinality):「現居地」是單一值(新的進來覆蓋舊的),「用過哪些技術」是可累積(PostgreSQL 跟 Redis 並存)。寫入前先判斷屬於哪種。
  • 分叉取代、不刪舊資料(Supersede-Fork):地址變了,舊卡不刪,標記「已於某日被取代」,新卡另立。就像修訂法律——舊條文不焚毀,而是註記被新法取代。這樣「現在」和「兩年前」的地址都查得到。
  • 記憶半衰期:半年前說「改用某瀏覽器」大概過時,半年前說「熱愛某語言」大概還算數。不同事實用不同指數衰減速度打分。
  • 把「今天」釘死成絕對日期:使用者說「昨天搬家」,這個「昨天」一定要在當下換算成 2026-06-17,不能存字串——否則一週後撈出來會以為是讀卡那天搬的。LLM 自己沒時鐘,得在它抽卡時「配一支手錶」,逼它把相對時間算成絕對日期。

不這樣設計會出什麼事?一個真實翻車

設計論講再多,不如一個翻車現場。某次縱向老化測試,系統產出 166 張狀態卡,事後一查——所有卡的 superseded_at(過時時間)欄位全是 NULL。意思是上面講得頭頭是道的「分叉取代」,過去幾個月一次都沒成功觸發過。

後果:你換過公司、搬過家,AI 卻永遠吐第一次聽到的舊值。問「我現在在哪上班?」它自信報出三年前的舊東家;極端一點,同一個人被記成「同時住台北又住京都」。

問題出在程式碼裡:寫入端抽出來的標籤,跟取代機制要求的判定條件「詞彙對不上」,每張卡都被誤當成「可累積」而從不退休。這就是為什麼那四條規則必須是硬規則——少一條,記憶會在你看不見的地方悄悄腐爛。 單日、單輪的 benchmark 永遠一片祥和;系統跑長、對話一深,隱藏的結構性 bug 才會浮現出來。

弱勝強:換更強的模型,反而更糟

還有一個更反直覺的案例,是這整章我最想丟出來的。同一套 fibon、同一批記憶卡,只把對話主腦從 Claude Sonnet 4.6 換成 Gemini 2.5 Pro(背景抽卡都用 Haiku 4.5):跨 Session 事實回溯,Sonnet 只有 16.7–20.8%,Gemini 卻有 64.6–72.9%——理應更強的旗艦輸了 46–52pp。多輪改寫題更誇張,Sonnet 28.6%、Gemini 那組幾乎全過。

先排除「Claude 抽的卡比較爛」——把抽卡也換成 Gemini 重跑,Claude 還是輸。真兇是:Sonnet 太聰明、太聽話。我在系統提示裡寫了條抗幻覺鐵律「沒看到的不准編」,一般模型會照做,但 Sonnet 對 prompt 過度服從,把資料庫撈回、明明正確的記憶卡當成「不該擅自宣稱知道的外部資料」一槍否決,回「抱歉,我無法存取你的外部系統」——等於白做 RAG。(這現象目前只記錄為待辦,受限預算還沒根治,誠實說在前面。)

補一句免得被誤會成 prompt 寫壞:這其實是「過度對齊(Over-alignment)」在 RAG 檢索下的副作用。模型太想當個誠實的乖小孩,反而失去了在上下文(Context)中靈活辨識結構化事實的彈性。換更聰明的模型,不會自動修好這件事,反而可能放大它。

(這個「弱勝強」案例我另外整理成一份白話的公開筆記+原始數據,放在 GitHub Gist:https://gist.github.com/AaronChuang/e4088e2724b7c8d7b22f5444796d6aae)

撈記憶:不要只押向量

很多人做 RAG 就是:問題轉向量 → 算 cosine → 撈 top 5。複雜場景會漏成篩子:對精確比對遲鈍、對中文錯字易脫靶、對時間查詢沒輒。所以我用「五路平行召回」再投票融合:

  1. 語意向量(Vector):抓「感覺對」但沒關鍵字的查詢。
  2. 標籤精確匹配(Exact Match):中文要先用 jieba 結巴斷詞(配繁中字典)才切得出正確的詞。
  3. 字元級模糊比對(n-gram):刻意不斷詞,用 n-gram 抓錯字(中文兩字一組 bigram、英文三字母一組 trigram)。
  4. 時間區間查詢(Temporal):把「上週」解析成日期區間,直接查時間軸。
  5. 圖譜關係展開(Graph):沿關聯往外踩一步,把「聊到 JWT 就帶出 OAuth」這種隱性關聯也拉進來。

五路結果用 RRF 投票,再做衰減/情境重排,最後只挑最精純的 5 張卡。真正難的從來不是「記住更多」,而是「記住但不要撈錯」。

知識卡最難:怎麼不讓它長成垃圾場

三種卡裡,知識卡最棘手——狀態卡有「唯一現值」、事件卡有「時間軸」,但知識沒有客觀唯一答案、而且會演化(JWT 最佳實踐、Reflection pattern 寫法、DDD 詮釋,每一兩年都在變)。放著不管,它很快變成一堆重複、過時、互相矛盾的爛卡——那就是負債不是資產。目前靠三道機制壓住熵增:

  1. Tag 正規化:語意相近的標籤自動合併,不讓 JWTjson web token 裂成兩棵樹。
  2. 新鮮度標記:超過 90 天沒驗證的卡,撈出來自動標「此摘要可能已過時」,AI 引用後主動問你要不要重驗。
  3. 綁定事件卡:每張知識卡連回「你在哪幾次對話真的討論過它」,有出處、可追溯,不是孤兒卡。

但老實說,這三道只是「延緩腐爛」,不是「保證新鮮」。知識卡會不會在更大規模、更長時間下還是劣化成垃圾場,是我還沒驗證、卻最想繼續解的開放難題。

一個很值錢的延伸:記憶就是省錢

對 LLM 來說,讀進去的 input token 比生成出來的 output token 便宜得多(多數供應商 output 單價是 input 的好幾倍)。所以一個知識點第一次想清楚就存成卡,下次當 input 讀回去,不必讓模型從頭「想」「寫」一遍,省下的正是最貴的 output。

在 Token 經濟學裡,復用不只是體驗問題,直接是成本問題。能當 input 讀進去的,就別逼 LLM 用最貴的 output 重新生成。

換句話說,個人助理級的 agent 不解 token 經濟學,再聰明也會被自己的運行成本壓垮。

帶得走的幾條原則

  1. 別把整段歷史硬塞:拆成原子化、可檢索的結構,模型看更少、看更準。
  2. 分清「現在」和「過去」:可變的事實與不可變的事件,用不同規則維運。
  3. 時間是第一公民:相對時間一定要在寫入當下釘死成絕對日期。
  4. 檢索別單押向量:精確、模糊、時間、關係,多路並行再融合。
  5. 記住但不要撈錯,比記住更多重要。
  6. 記憶就是省錢:能復用的知識,省的是最貴的 output token。

最後,留一題給你一起燒腦

順著這個「弱勝強」往外想一題,丟給你一起燒腦:工程做得好,模型是不是就可以不用那麼好?如果一條 GUARD 護欄、一套五路檢索、一層記憶卡,就能讓較弱、較便宜的模型在真實任務上贏過旗艦——那是不是代表,當系統層打磨到位,底層模型的「絕對智商」就沒那麼關鍵了?省下的模型費用,該不該轉投到工程?

但反過來也成立:越聰明、越聽話的模型,越容易被你寫死的護欄綁住手腳。所以到底是「把模型換更強」邊際效益高,還是「把工程做更好」邊際效益高?這題我沒有定論,但我不想只有自己一個人在這裡轉——如果是你,你會把下一塊錢押在模型,還是押在工程?


這是把第三章濃縮、可獨立閱讀的設計主張版。完整章節(每條規則的資料表設計、衝突仲裁、3×6 多維結構、那場翻車的完整排查紀錄,以及一張標出每個 LLM 呼叫位置的循序圖)中英雙語都有:

👉 完整章節連結:https://fibon.stepbyday.com/chapters/03-memory/

先打個預防針:這套記憶系統我前後弄了 2–3 個月、到現在都還沒完全收工,所以完整章節是全站最長的一篇,要看請有點心理準備,或挑有興趣的小節跳著讀就好。

端午連假愉快。

更新 · 2026-06-20(勘誤補充)

一位讀者點出一個重要的分寸——前面把「Sonnet 慘敗 = GUARD 過度對齊(false refusal/假性拒答)」講得太篤定了。嚴格說,這是高可信度的「推測」,不是因果上的「證明」

撐住這個推測的證據有兩條:

  1. 換成 Gemini 跑同一批記憶卡就高 → 排除了「卡片品質」這個變因;
  2. Sonnet 的原始回應是拒答(「我無法存取你的外部系統」),而不是給出錯答案 → 比較像 false refusal,不像推理算不出來。

但要拿到鐵證,得像《Mitigating False Refusal in Language Models via Single Vector Ablation》(ICLR 2025)那樣,在開源模型上把那條「假性拒答向量」抽出來、消去,再看回溯率會不會回升。而 Claude 閉源、只有 API,這種白盒手術對 Sonnet 根本做不到——所以這一段請讀成「強力推測」,先別當定論。

(這也對應〈深入剖析 F〉的「你改的是哪一層」四層金字塔:fibon 的修法落在前三層的外殼,那篇 ablation 動的是第四層的模型內部,正是 fibon 永遠不踏進去的禁區。)


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
amyc
iT邦新手 5 級 ‧ 2026-06-19 06:07:38

感謝這篇,看得很過癮。我不是工程背景,純粹是 AI 工具的重度使用者,只敢從「用」的角度丟一個小觀察,不一定對。
您認為 Sonnet 太聽話,把自己撈回來的正確記憶卡當成「不能擅自宣稱知道的外部資料」而拒答——這段我特別有感。我平常在用的內建跨對話記憶,呈現方式不太一樣:它不是把記憶擺成「你去外面查到的東西」,而是直接跟模型講「這些是你自己過去對話的記憶,當你本來就知道的事去用」。一旦框成「自己的」,模型用起來就不會覺得在越界。
所以讀您的案例,我會猜卡點也許不在模型比較弱,而在那條規則把卡片推去了「外部/不可信」那一側——越聽話的模型反而越不敢碰。會不會不用真的逐家重調護欄那麼累,只要在前面先講清楚「資料庫撈回來的是你已授權的記憶、不是對外呼叫」,它就敢認了?
外行淺見,講錯見諒,謝謝您連翻車都寫出來,感謝分享。

先謝謝你的留言,我真的把這件事跑了一遍。這篇算實驗回報,也會整理進之後的深度剖析。

先把你的點子用我的話複述一次:我說「越聰明的模型,越容易把自己撈回來的正確記憶,當成不確定的外部資料而一槍否決」。你說,問題的根可能不在逐家調護欄強弱,而在框定——與其把那張卡端上來說「這是來路不明、要存疑的資料」,不如說「這是你自己的、早就知道的事」,模型自然就敢用了。

這個方案,其實試過了——而且試了兩次:一次是過去的我,一次是這回為了回覆你又重跑一遍。

結果一:我引用的那個慘數字(16.7%),現況早就不是了

我回頭一量才發現,現在的系統在「我住哪、我在哪上班」這種題目上幾乎全對,連比較難的題目也有六成左右。那 16.7% 是某個時間點的舊快照:中間幾刀我沒特別宣傳的修復(讓系統一定會把記憶塞給模型、把「搬家後舊地址還賴著」這種汰換修好、讓 AI 自己寫的信也存得起來),早就把那個洞補掉一大半了。所以那個「強模型輸給弱模型」的洞,是被工程慢慢補起來的,不是靠動護欄

結果二:你的框定點子,我照做之後反而更糟

我把它做成一個開關:打開時,把使用者的所有記憶卡都改框成「這是你自己的、直接信」。在兩個對話模型上 A/B 實測——分數掉了,難題從六成掉到五成。原因很反直覺:對一個本來就很聽話的聰明模型,「叫它無條件信任全部記憶」反而讓它對使用者隨口講的普通事實變得更小心翼翼

後續怎麼修:不是「全部都信」,而是「只信對的那一類」

而我翻自己的開發紀錄,發現過去的我早就踩過這個雷、也早就修了——修法不是把全部記憶都當成「你自己的」,而是把這條「這是你自己的、可以直接信」的指令,套在「AI 自己寫出來的文件」(信、清單、計畫)那一類卡上,而且只有當下真的有這類卡時才注入。其他使用者隨口提的事實,維持原本的謹慎處理。

修完的結果

這個「縮小範圍」的版本,把「我上次寫的那封信/那份清單,開新視窗還記得嗎」這一整類問題,從幾乎全錯修到能用,而且沒有拖累普通事實的回溯。


所以我想跟你說的不是「你錯了」——剛好相反。你指出的核心「框定,會決定模型敢不敢用一段記憶」完全正確,這正是系統現在對「AI 自己寫的東西」採用的做法。真正的重點在範圍:對「AI 自己的產出」放寬信任,是解藥;對「使用者隨口提的事實」也一視同仁地放寬,就成了毒藥。

再補一個你可能會追問的:那條害聰明模型反噬的抗幻覺護欄,我本來打算怎麼根治?目前的方向是把它整條移出 prompt——不要再靠「寫一句規則叫模型自律」(越聰明、越聽話的模型反而會過度服從、連正解都否決),改用工程手段在程式碼層把關(例如回答後再跑一道驗證,檢查它有沒有亂編),這樣防線就不必看模型的臉色。但這條路成本不低(等於每個回答都多一道工序),所以目前是擱置狀態,先讓前面那些檢索/汰換的修復頂著。

你的一句話激起了我的好奇心,也順手逼我把這段早就寫完、其實有點半忘了的程式碼重新審查了一遍;最後還從外部獨立驗證了一個連我當初都沒寫清楚的架構取捨。這種來回,正是我把開發日誌攤開來公開連載最想換到的東西。真心感謝——這段我會原原本本寫進〈深入剖析 G:跨廠商模型行為心理學〉。

1
p206s16cc
iT邦新手 5 級 ‧ 2026-06-19 09:11:50

樓主,
這篇讓我想到一個我自己一直在區分的問題。
記憶(Memory)與身份(Identity)究竟是不是同一件事?
如果把所有 Memory 看成 Event 的累積,那麼系統確實能回答:
「過去發生過什麼」
但我比較好奇的是:
「這些事件累積之後,系統本身變成了什麼?」
例如:
使用者喜歡技術討論、
偏好結構化回答、
討厭冗長說明。
這些可以作為 Memory 被存起來。
但它們什麼時候會開始形成一種穩定傾向(tendency)?
又或者永遠只是被動召回的資料?
我最近在做 OSD Behavioral Probe 時,剛好一直在看這類問題:
Event → Memory → State → Trajectory
其中 State 這層好像很容易被忽略。
不知道你後面 Memory 系列會不會碰到:
「記住了什麼」

「因此變成什麼」
之間的差異。

樓主在文末的這題很燒腦,但我覺得問題框架本身有個預設值得先拆一下。
「模型 vs 工程」這個對立,其實是在問兩種不同的東西:
模型投資買的是能力上限——這個系統最強能做到什麼。
工程投資買的是行為的可預測性——這個系統在真實場景下有多穩定、多可控。
你說的「弱勝強」現象,本質上是:在有限的任務範圍內,可預測性的價值超過了能力上限的價值。 你的 GUARD 護欄、五路檢索、記憶卡,不是讓小模型變聰明了,是讓它的行為邊界變得清楚了。
但這裡有個反例需要考慮:當任務本身超出你工程能設定的邊界時,工程的邊際效益會急速下滑。 你的護欄寫死了它能處理什麼——那護欄外面的東西怎麼辦?旗艦模型的優勢就在那個邊界外面。
所以我不會說「押模型」還是「押工程」,我會問:你現在最大的損失,是來自能力不夠,還是行為不可預測?
如果是後者,工程邊際效益高。如果是前者,換模型比較直接。

我自己研究的方向讓我有個偏見:我覺得大多數系統現在的問題不是模型不夠強,而是根本不知道模型在哪個時刻、往哪個方向偏掉了。那個可觀測性的問題,才是工程層現在最大的空白。
下一塊錢?我會押在「知道系統在做什麼」上面,不管底下是弱模型還是旗艦。

謝謝你這串。先講句老實話:你戳的這塊,是我當初做記憶系統時根本沒想到的一塊。我那時滿腦子都在「怎麼把事情記對、開新視窗還撈得回來」——也就是「記住了什麼」;你問的是另一個方向:這些東西累積久了,系統自己變成了什麼?我回頭翻程式碼才發現,我從來沒認真處理過。

在 fibon 裡,「你討厭冗長」這種偏好不會永遠只是一張等人來查的卡。系統每注意到一次就加一分,累積到一定程度,它就從「要用到才撈出來」變成「每次都先放進去、預設就照做」——那一刻,它已經從「記憶」變成「習慣」,也就是你說的身份。

尷尬的是:這場轉變,系統一點記錄都沒留。 事實的變化(你搬家、換工作)它記得清楚——改了什麼、因為哪句話;它自己猜的東西(「你大概對咖啡因敏感」)記了當下的理由,但重算就蓋掉;而最像身份的那層,只剩一個計數器——哪天跨過門檻、被哪幾段對話養出來的,通通沒記。它就這樣悄悄變成那個樣子,自己也不知道。

所以你那句「又或者永遠只是被動召回的資料?」我可以明確回答:不是,它確實會變成主動的傾向;但它在變的當下,沒記得自己在變。至於你那層 Trajectory,我想了一輪,覺得實作上它會塌回「狀態」——看一串事件、歸納出結論,結論還是寫成一張卡。所以缺的不是再加一層抽象,而是兩件很土的事:把過去留著、定期回頭重算。我系統偏偏兩個都沒做。

回頭追這件事,我發現它不只是「漏了一個功能」,而是一個更有意思的錯:我太早把「記憶」這個抽象收成了「事件→狀態」那條乾淨的管線,等於用「我的工具做得到什麼」,把「系統會變成什麼」這個問題悄悄定義掉了。軟體開發難免漏東西,但這個錯有趣到我打算另寫一篇專門談它——談我們怎麼在用一個工具回答問題的同時,不小心把問題給殺了。


至於你拆我文末那題「模型 vs 工程」——你拆得比我原本問得好太多。「模型買能力上限,工程買行為的可預測性」,把我攪在一起的東西分乾淨了;「弱勝強」說白了就是:在範圍固定的任務裡,可預測性的價值贏過能力上限。

我補一個你少講、但其實是前提的東西:工程為的是把模型框住、避免它暴衝——這就是刻意「閹割強模型」的取捨,而任何「誰比較好」都得在同樣條件下才有意義。兩個員工一強一弱、做同一份照 SOP 的活,強的東想西想反而略低——大家會說那是擺錯位置,該讓他去做 RD。結論就是隨才器使:抽象地問「押模型還是押工程」根本問錯,得先釘住任務。那個 16.7% 就是「強員工在 SOP 上太小心」:Sonnet 太聰明,反過來質疑自己撈回的正解。

但模型跟員工不一樣,這點剛好把球丟回你那邊:你沒辦法事先分案。 同一個模型既是 SOP 工又是 RD 工,任務還混在同一段對話裡一句一句來。所以「隨才器使」對模型不是聘人的決定,是每一輪的即時決定——而要調度,你得先看得見此刻的狀態。

所以你那句「下一塊錢押在知道系統在做什麼」,我不只同意、還想推一步:可觀測性不是第三個選項,是讓那道選擇題變得可回答的前提——你不先知道損失來自能力還是行為,根本沒資格選押哪邊。只是要分清楚:看得見不等於控制得住,它買的是「答得出問題」,不是「行為變乖」。

最妙的是:你押可觀測性,而你自己就在造那把尺——OSD 不就是嗎。你問我下一塊錢押哪,早就用行動回答了。

p206s16cc iT邦新手 5 級 ‧ 2026-06-20 08:47:41 檢舉

「用工具做得到什麼,悄悄把問題定義掉了」——這句我會記很久。這不只是你的軟體開發漏洞,是我在做研究時一直在防的同一個陷阱:先決定觀測手段,手段會反過來決定你看得到什麼問題。你親手撞上了這個,而且看見了,這比補功能本身更有價值,等你那篇文章。
「最像身份的那層只剩一個計數器,跨過門檻的那一刻沒留記錄」——這句話幫我把 Trajectory 的價值講清楚了。不是要多一層抽象,是要把「變化發生的那個過程」本身留下來,不只留結果。你說的「把過去留著、定期回頭重算」,這兩件土事,我覺得判斷是對的——不需要新概念,需要的是歷史不被覆蓋。如果你真的把這個接進 fibon,那會是第一個外部系統把 Trajectory 落地,不只是驗證我的觀測工具,是直接把它長進你的架構裡了。
Sonnet 那個例子也順手解了我自己一個案例。我手上有一個「強模型在簡單任務上過度思考、自己反而幫倒忙」的觀察案例,跟你的 16.7% 是同一個現象的兩種表現——不是模型不夠強,是模型的聰明在錯誤的場合被啟動。可預測性低,不是因為它笨,是因為它太想表現。
「你押可觀測性,你自己就在造那把尺」——被你這樣講出來,我才意識到我從來沒把這句話說得這麼直白。謝謝你幫我把這個說清楚。

「模型 vs 工程」這個問題我自己也在用另一套框架慢慢拆,之後比較成形了再跟你聊。

1
coco40725
iT邦新手 5 級 ‧ 2026-06-20 00:46:36

樓主~ 文章很讚 💯💯

弱勝強的情境

我覺得你那個弱勝強的情境,可能會讓別人誤會強推理模型不擅長記憶追溯 (因為直覺上大家會認為強推導能力的模型就是強模型 ;反之是弱模型)

我認為今天真正的問題出在於 "模型對於 Harmless-Helpful-Honest (HHH) 的對齊程度 ",從你的結果來看,我傾向下這樣的結論:
兩個模型對於 "記憶追朔" 這個任務是 Gemini 2.5 Pro 優於 Claude Sonnet 4.6,原因 "推測"是Claude Sonnet 4.6 over-alignment 導致他一直拒絕回答,使最終結果不理想。
(若要進一步證明真的是 over-alignment 的話,那你需要拔掉或抵消 Claude Sonnet 4.6 負責 HHH 的部分,類似 https://openreview.net/forum?id=SCBn8MCLwc 這篇論文在幹的事,不然都是推測)

因此,你如果直接基於這個結果下: 記憶追溯的情境下,弱模型(弱推導能力)優於強模型(強推導能力) 這樣的結論,那可能不太準確。今天只是因為這個強推導能力的模型他有 over-alignment 的問題,所以才表現不好。(如果他有辦法抵銷掉 over-alignment 那可能又是另外一回事了)

工程 VS LLM 模型

如果是你,你會把下一塊錢押在模型,還是押在工程?

我認為需要思考的問題是:
假設你要開發一個需要 LLM 整合的系統,那麼哪些功能要用工程處理? 哪些功能要用 LLM 處理?

  • 工程 帶來的特性是: 穩定性與高可掌握性,決定了系統的最低功能,即下限。
  • LLM 帶來的特性是: 變化性與靈活性,決定了系統的上限。
    因此甚麼功能要用工程 or LLM,取決於你希望並注重這個功能有什麼樣的特性。

舉個例子: 查找指定月份年份的商店財報,這裡就有兩種選擇:

  1. 你可以直接寫一個 SQL,保證每一次查找的邏輯都是相同的,但也就只能查這個資料。
  2. 寫 prompt 教 LLM 幫你產生 SQL,不保證每一次的邏輯,但是如果LLM 想要做額外的推論,他有能力自己搜出對應的資料。

方法1和2 沒有誰對誰錯,取決於你想要你的系統有甚麼功能。

謝謝,這則點得很準,而且把我那個案例的「危險誤讀」抓出來了。

先回你最重要的那一刀。 你抓得對——「弱勝強」這個標籤,確實會讓人以為「強推理模型不擅長記憶追溯」。但老實說,那個標籤我是刻意這樣下的,帶點釣魚:我的目的很簡單,就是想讓那些準備閉著眼睛拿強模型當系統基底的人,看到這個反直覺的標題會停下來、想一想、測一測。所以就算它造成一點誤會,那個「停一下」正是我要的。

順帶澄清一個前提:文章裡說的「強/弱」是相對的,也不是我主觀判定——依公開跑分表的名次,Sonnet 4.6 排在 Gemini 2.5 Pro 之前(相對強),結果在「記憶追溯」這任務上反而輸給它(弱勝強),這個反差才是我想戳的點。(跑分表持續更新,這兩個版本現在都已被新版洗掉,連結看的是現況:Agent Arena。)

至於背後真正的機制,你說得完全對:不是推理弱,是 over-alignment(過度對齊) 害的。先給其他讀者補個底:模型訓練時要對齊 3H——Helpful(有用)、Honest(誠實)、Harmless(無害);Sonnet 是那種「3H 學得太用力」的模型,結果負責 Honest/Harmless 的那部分過度觸發,把自己從資料庫撈回來、明明正確的記憶卡,當成「我不該擅自宣稱知道的外部資料」一槍拒答。所以它不是答不出來,是拒絕回答。學界給這現象一個正式名字,正是你引的那篇在處理的:false refusal / exaggerated safety(假性拒答 / 過度安全)

關於你說「要證明是 over-alignment,就得拔掉 HHH 那部分」,你引的那篇做的正是這件事,而且它剛好揭示了一個「層級」問題。 那篇(《Mitigating False Refusal via Single Vector Ablation》,ICLR 2025)是白箱方法:它伸進模型內部,抽出一條「假性拒答向量」,把它消去,拒答率就降、安全性還保得住。重點是它得摸到模型內部的表徵,這是白盒手術。

這剛好對上我在〈深入剖析 F〉有提到「你改的是哪一層」四層金字塔(從淺到深,改的東西越往下越深入大腦):

  • 第一層:改外殼提示詞 / 記憶卡(prompt、harness)——最淺、最便宜、隨時可逆
  • 第二層:讓 AI 自己長出外接工具
  • 第三層:改線上原始碼(fibon 的自我進化引擎最深就踩在這層)
  • 第四層:伸進大腦改參數 / 內部表徵(權重次元)——最深的禁區

fibon 整個架構被鎖在前三層(外殼),最深只到第三層(改自己的原始碼),永遠碰不到第四層。而我這次修 over-refusal,用的其實是最淺的第一層——把記憶卡的框定改成「這是你自己的、可信的」。你引的那篇 ablation,則是第四層那一側:伸進凍結的大腦裡動內部表徵(只是它 training-free,消去一條向量,比「打掉重練權重」輕)。

所以你說的「拔掉 Sonnet 的 HHH 來證明」這條,對 Sonnet 直接做不到,兩個原因:(1) Claude 閉源、只有 API,你根本伸不進去抽向量——白盒要開源權重才行;(2) 就算做得到,那也是第四層,fibon 的哲學死活不踏進去。要做那個乾淨的因果證明,得在開源模型上重現同現象、再 ablate

至於我手上的證據算不算「證明」:你說得對,沒做介入實驗,嚴格講都是推測。最硬的一條是 raw response 本身——Sonnet 不是給錯答案,是直接拒答(「我無法存取你的外部系統」);算不出來會亂答,會拒絕回答才講這種話,這個簽名像 false refusal、不像推理失敗。另一條閉源能做的行為介入也指向同一方向:在 prompt 層把「AI 自己寫的內容」那類卡標成「你自己的產出、可信」,Sonnet 就不再對那類卡拒答、那一塊的回溯率回來了——動的是「信任框定」這個對齊層的旋鈕,不是推理。

(這裡得誠實補一句,免得誤導:把這條信任無差別套到所有記憶卡,反而更糟、會讓 Sonnet 對普通事實更保守——真正有效的是縮小範圍,只給「AI 自寫」那類。而 16.7%→約六成的主升幅,其實主要來自檢索與汰換的工程修復,不是信任框定。所以「信任框定能救回溯」這句話只在很窄的範圍成立,別擴大解讀。)

這條「推測 vs 證明」的界線我會在文裡講清楚,不讓讀者把它當定論。謝謝你把這個分寸點出來。


第二題,你那個「下限 vs 上限」的拆法,我直接收下,而且它比我原本的問法好。

用你的話:工程買的是穩定、可掌握——它決定系統的下限(最低保證);LLM 買的是變化、靈活——它決定上限(能做到多好)。 哪個功能該用哪個,看你要那個功能有什麼脾氣。你那個 SQL 的例子很精準:寫死 SQL =每次邏輯都一樣、但只能查這個;教 LLM 產 SQL =不保證每次一樣、但它能自己多推一步去撈別的。

我只補一個你那段藏著、但沒講白的維度:你付不付得起「不可預測的失敗」。 寫死的 SQL 會「可預測地失敗」——你很清楚它查不到什麼;LLM 產的 SQL 會「不可預測地失敗」——它可能多撈到對的,也可能錯得很細微、而你當下看不出來(英文叫 subtly wrong:答案表面看起來合理,但有個小地方是錯的,不仔細查不會發現)。所以選哪個,除了「你要什麼脾氣」,還要問一句「這裡錯了,我賠得起嗎」:查財報你要那個確定的下限(數字錯了是災難),做探索性分析才值得用 LLM 的上限。

而你敢把 LLM 的上限疊在工程的下限上面——前提正是上一位讀者講的可觀測性:你得看得見 LLM 那一半什麼時候漂掉、悄悄破了你的下限。所以你們兩位的點剛好接起來:工程設下限、LLM 抬上限、可觀測性讓你敢信任那個上限不會偷偷砸了下限。 這也回頭解釋了我那個「弱勝強」其實是一次失敗的下限工程——我想用 GUARD 護欄(工程)把強模型的下限拉穩,結果那道護欄反而把它的表現壓到了下限以下。

我要留言

立即登入留言